home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / tuwtcpsr / icmp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-19  |  4.3 KB  |  78 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "ip.h"
  4. #include "icmp.h"
  5. #include "timer.h"
  6.  
  7. #include "nettrace.h"
  8.  
  9.  
  10. #define noDEBUG
  11.  
  12. static void pingtmo(TIMER);
  13. static int icmp_pingstate;
  14. static TIMER icmp_pingtm;
  15. static int pingseq;
  16. static PACKET *sent;
  17. static int snt_len;
  18. struct redent redtab[REDIRTABLEN];int rednext = 0;int holdback = 0;
  19. long icmp_counts[2] = {0L,0L};
  20.  
  21. int icmp_init(void)
  22. {
  23. int i;
  24.     if(!ip_open(IP_ICMP,icmp_handler,(int (*)(IP *))NULL)) return(FALSE);
  25.     icmp_pingstate = PGWAITING;
  26.     for(i=0; i< REDIRTABLEN; i++)
  27.         redtab[i].dst_inaddr = 0L;
  28.     return(TRUE);
  29. }
  30.  
  31.  
  32. int icmp_handler(PACKET *pkt,int len,INADDR fhost){register IP *ip;register struct ping *e;struct redirect *rd;struct destun *pdp;u_short osum;char *data1, *data2;int i;
  33.     ip = ip_head(pkt);    e = (struct ping *)ip_data(pkt);    osum = e->pchksum;    e->pchksum = 0;    if(chksum((u_short *)e,len,0) != osum) 
  34.     {        ip_free(pkt);        return(FALSE);    }    e->pchksum = osum;    icmp_counts[0]++;
  35.     switch(e->ptype) 
  36.     {        case ICMP_ECHOREQ:            /* ping */            e->ptype = ICMP_ECHOREP;            e->pchksum = 0;            e->pchksum = chksum((u_short *)e,len,0);            ip->src_inaddr = ip->dst_inaddr;            ip->dst_inaddr = fhost;            icmp_counts[1]++;
  37.             i = ip_send(IP_ICMP, pkt, len, fhost);            ip_free(pkt);
  38.             return(i);                case ICMP_DESTIN:            pdp = (struct destun *)e;            ip_dudemux(&pdp->dip);    /* DDP - upcall handler */            break;
  39.         case ICMP_SOURCEQ:
  40.             holdback++;            /* hold back data - dst busy */            break;
  41.         
  42.                 case ICMP_REDIR:            rd = (struct redirect *)e;            for(i=0; i<REDIRTABLEN; i++)                if(redtab[i].dst_inaddr == rd->rdip.dst_inaddr) 
  43.                 {                    redtab[i].gw_inaddr = rd->rdgw;                    ip_free(pkt);                    return(TRUE);                }            redtab[rednext].dst_inaddr = rd->rdip.dst_inaddr;            redtab[rednext].gw_inaddr = rd->rdgw;            rednext++;            if(rednext >= REDIRTABLEN) rednext = 0;            break;
  44.  
  45.         case ICMP_ECHOREP:            if(e->pseq != pingseq-1) 
  46.             {                ip_free(pkt);                return(FALSE);            }            data1 = ((ICMP_PACKET *)pkt)->icmp_data;            data2 = ((ICMP_PACKET *)sent)->icmp_data;            for(i=0; i < snt_len; i++)                if(*data1++ != *data2++) 
  47.                 {                    icmp_pingstate = PGBADDATA;                    ip_free(pkt);                    return(FALSE);                }            icmp_pingstate = PGSUCCESS;            ip_free(pkt);            break;        case ICMP_TIMEX:            break;
  48.                     case ICMP_PARAM:            break;
  49.                     case ICMP_TIMEREQ:            e->ptype = ICMP_TIMEREP;            e->pchksum = 0;
  50.             e->pchksum = chksum((u_short *)e, (int)sizeof(struct tstamp),0);            ip->src_inaddr = ip->dst_inaddr;            ip->dst_inaddr = fhost;            icmp_counts[1]++;
  51.             i = ip_send(IP_ICMP, pkt, (int)sizeof(struct tstamp), fhost);            ip_free(pkt);
  52.             return(i);
  53.         case ICMP_INFO:            break;
  54.                 }    ip_free(pkt);
  55.     return(TRUE);}
  56.  
  57.  
  58.  
  59. int icmp_dstun(INADDR inaddr ,IP *ip,int type)
  60. {
  61. PACKET *p;register struct destun *d;int i;
  62.     p = ip_alloc(512, 0);    if(p == NULL) return 0;
  63.     d = (struct destun *)ip_data(p);    d->dtype = ICMP_DESTIN;    d->dcode = type;    for(i=0; i<(int)sizeof(IP)+8; i++)        ((char *)&d->dip)[i] = ((char *)ip)[i];    d->dchksum = 0;    d->dchksum = chksum((u_short *)d, (int)sizeof(struct destun),0);    icmp_counts[1]++;
  64.     i = ip_send(IP_ICMP, p, (int)sizeof(struct destun), inaddr);
  65.     ip_free(p);    return(i);}
  66.  
  67. icmp_ping(INADDR fhost, int length){PACKET *p;register struct ping *e;register char *data;int i;
  68.     p = ip_alloc(40, 0);
  69.     if(p == NULL) 
  70.     {        return PGNOSND;    }    e = (struct ping *)ip_data(p);    e->ptype = ICMP_ECHOREQ;    e->pcode = 0;    e->pid = 0;    e->pseq = pingseq++;
  71.     /* Put 256 random numbers in the packet. */    data = ip_data(p) + ICMP_PKTSIZE;    for(i=0; i<length; i++) *data++ = rand();
  72.     /* Calculate the checksum */    e->pchksum = 0;    if((ICMP_PKTSIZE+length)&1)        *data = 0;    e->pchksum = chksum((u_short *)e, (ICMP_PKTSIZE+length+1),0);    icmp_pingstate = PGWAITING;    sent = p;    snt_len = length;    icmp_pingtm = tm_alloc();    if(icmp_pingtm < 0) 
  73.     {        ip_free(p);        return(PGNOSND);    }    tm_set(tm_msec(ECHO_TIMEOUT), pingtmo, icmp_pingtm );    icmp_counts[1]++;
  74.     if(ip_send(IP_ICMP, p, ICMP_PKTSIZE+length, fhost) <= 0) 
  75.     {        tm_free(icmp_pingtm );        ip_free(p);        return(PGNOSND);    }    while(icmp_pingstate == PGWAITING)        net_demux(FALSE,DEMUX);    tm_free(icmp_pingtm );    ip_free(p);    sent = 0;    return(icmp_pingstate);}
  76. static void pingtmo(TIMER tm) 
  77. {
  78.     if(icmp_pingtm == tm)        icmp_pingstate = PGTMO;}